package com.flightgame.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.flightgame.hibernate.Airport;
import com.flightgame.hibernate.AirportDao;
import com.flightgame.hibernate.Flight;
import com.flightgame.hibernate.FlightDao;
import com.flightgame.hibernate.ItemDao;
import com.flightgame.hibernate.Ownership;
import com.flightgame.hibernate.OwnershipDao;
import com.flightgame.hibernate.UserDao;
import com.flightgame.tools.Builder;
import com.flightgame.tools.Utils;

@Service
public class FlightServices {
	@Autowired
	private OwnershipDao ownershipDao;
	@Autowired
	private AirportDao airportDao;
	@Autowired
	private FlightDao flightDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private ItemDao itemDao;
	@Autowired
	private DBServices dbServices;
	@Autowired
	private Utils utils;
	
	public int createFlight(String username,String itemname,int ownershipId_aircraft){
		Ownership ownership = ownershipDao.getOwnership(ownershipId_aircraft);
		Airport airport = airportDao.getAirportByCode(ownership.getAirportcode());
		
		if(userDao.isUserExist(username) == false) return utils.INVALID_USERNAME;
		else if(itemDao.getItem(itemname) == null) return utils.INVALID_ITEMNAME;
		dbServices.deletePreviousFlights(ownershipId_aircraft);
		
		Builder builder = new Builder();
		Flight flight = builder.flightBuilder(username, itemname, airport.getLat(), airport.getLon(), 0, ownershipId_aircraft);
		
		flightDao.addFlight(flight);
		
		return utils.SUCCESS;
	}	
	
	public String refreshFlightPosition(int ownershipId_aircraft,double newLat,double newLon,double newAlt){
		Flight flight = flightDao.getUserFlight(ownershipId_aircraft);
		Utils utils = new Utils();
		Ownership ownership = ownershipDao.getOwnership(ownershipId_aircraft);
		
		String latLonHistory = flight.getLat() + "," + flight.getLon() + "," + flight.getAltitude();
		
		// Fuel consumption
		double distance = utils.distanceBetweenCoordinates(flight.getLat(),flight.getLon(),newLat,newLon);
		double consumption = distance / Double.parseDouble(utils.getParameterValue(itemDao.getItem("fuel1").getParams(),"unitConsumption"));
		double currentFuel = Double.parseDouble(utils.getParameterValue(ownership.getParams(),"fuel"));
		double newFuel = currentFuel - consumption;
		
		ownershipDao.setOwnershipParam(ownershipId_aircraft,"fuel",newFuel+"");

		flightDao.updateFlight(ownershipId_aircraft, newLat, newLon, newAlt,latLonHistory);

		return latLonHistory;
	}
	
	public int endFlight(int ownershipId_aircraft,String airportCodeLanded){
		flightDao.deleteFlight(ownershipId_aircraft);
		
		if(airportDao.getAirportByCode(airportCodeLanded) != null){
			ownershipDao.changeAircraftAirport(ownershipId_aircraft, airportCodeLanded);
			return utils.SUCCESS;	
		}
		return utils.NO_AIRPORT_WITH_CODE;
	}
	
	public int getFuelOfAircraft(int ownershipId_aircraft){
		String param = ownershipDao.getOwnershipParam(ownershipId_aircraft,"fuel");
		if(param.equals("")) param = "-1";
		double fuel = Double.parseDouble(param);
		
		return (int) fuel;
	}
	
	public int decreaseIncreaseFuelOfAircraft(int ownershipId_aircraft, int change){
		int currentFuel = getFuelOfAircraft(ownershipId_aircraft);
		
		currentFuel += change;
		ownershipDao.setOwnershipParam(ownershipId_aircraft,"fuel",currentFuel+"");
		
		return currentFuel;
	}
	
	public Flight getFlight(int ownershipId_aircraft){
		return flightDao.getUserFlight(ownershipId_aircraft);
	}
	
	public int buyFuelToAircraft(int ownershipId_aircraft,int ownershipId_gasStation,int quantity){
		Ownership ownershipAircraft = ownershipDao.getOwnership(ownershipId_aircraft);
		Ownership ownershipFuel = ownershipDao.getOwnership(ownershipId_gasStation);
		
		if(ownershipAircraft == null || ownershipFuel == null) return utils.INVALID_ID;
		
		int quantityOfFuel = quantity;
		int emptyFuel = Integer.parseInt(ownershipDao.getOwnershipParam(ownershipId_aircraft,"fuelLimit")) - getFuelOfAircraft(ownershipId_aircraft);
		if(emptyFuel < quantityOfFuel) quantityOfFuel = emptyFuel;
		int priceOfFuel = itemDao.getItem("fuel1").getPrice() * quantityOfFuel;
		int userCredits = userDao.getUser(ownershipAircraft.getUsername()).getCredits();
		if(userCredits < priceOfFuel) return utils.INSUFFICIENT_CREDITS;
		
		userDao.transferCredit(ownershipAircraft.getUsername(),ownershipFuel.getUsername(),priceOfFuel);
		decreaseIncreaseFuelOfAircraft(ownershipId_aircraft,quantityOfFuel);
		
		return utils.SUCCESS;
	}
}
